package io.github.wppli.domain.posts.service;

import cc.jq1024.middleware.redisson.IRedissonClientService;
import cc.jq1024.middleware.redisson.IRedissonService;
import io.github.wppli.domain.posts.event.CalculatePostsTfIdfEvent;
import io.github.wppli.domain.posts.model.aggregate.PublishPostsAggregate;
import io.github.wppli.domain.posts.model.entity.CollectPostsEntity;
import io.github.wppli.domain.posts.model.entity.PostEntity;
import io.github.wppli.domain.posts.model.entity.PublishPostsEntity;
import io.github.wppli.domain.posts.model.entity.LikePostsEntity;
import io.github.wppli.domain.posts.model.valobj.PostsLikeCountVO;
import io.github.wppli.domain.posts.model.valobj.UserPostsBehaviorType;
import io.github.wppli.domain.posts.repository.IPostsRepository;
import io.github.wppli.domain.posts.model.entity.PostsTfIdfTaskEntity;
import io.github.wppli.domain.recommond.model.entity.PostsContentEntity;
import io.github.wppli.types.event.BaseEvent;
import io.github.wppli.types.event.TaskStateVO;
import io.github.wppli.types.exception.AppException;
import io.github.wppli.types.snow.SnowflakeIdGenerator;
import lombok.AllArgsConstructor;
import org.redisson.api.RSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author li--jiaqiang 2025−03−11
 */
@Service
@AllArgsConstructor
public class PostsService implements IPostsService {

    private static final Logger log = LoggerFactory.getLogger(PostsService.class);
    private final IPostsRepository postsRepository;
    private final SnowflakeIdGenerator snowflakeIdGenerator;
    private final IRedissonService redissonService;
    private final IRedissonClientService redissonClientService;
    private final PostsCountService postsCountService;
    private final CalculatePostsTfIdfEvent calculatePostsTfIdfEvent;

    @Override
    public void publishPosts(PublishPostsEntity publishPostsEntity) {
        // 1.
        publishPostsEntity.setId(snowflakeIdGenerator.nextId());

        // 2. 发布消息队列
        CalculatePostsTfIdfEvent.CalculatePostsTfIdfMessage message =
                new CalculatePostsTfIdfEvent.CalculatePostsTfIdfMessage(
                        publishPostsEntity.getAuthorId(), publishPostsEntity.getId(),
                         publishPostsEntity.getContent(), UserPostsBehaviorType.PUBLISH
                );
        BaseEvent.EventMessage<CalculatePostsTfIdfEvent.CalculatePostsTfIdfMessage> calculatePostsTfIdfMessageEventMessage = calculatePostsTfIdfEvent.buildEventMessage(message);
        PostsTfIdfTaskEntity taskEntity = PostsTfIdfTaskEntity.builder()
                .userId(publishPostsEntity.getAuthorId().toString())
                .topic(calculatePostsTfIdfEvent.topic())
                .state(TaskStateVO.create)
                .message(calculatePostsTfIdfMessageEventMessage)
                .messageId(calculatePostsTfIdfMessageEventMessage.getId())
                .build();

        PublishPostsAggregate publishPostsAggregate = new PublishPostsAggregate(publishPostsEntity, taskEntity);
        postsRepository.publishPosts(publishPostsAggregate);

    }

    @Override
    public List<PostEntity> listPosts(Long authorId) {
        List<PostEntity> postEntities = redissonService.getValue("POSTS_LIST_" + authorId);
        if (postEntities != null) {
            return postEntities;
        }
        postEntities = postsRepository.listPosts(authorId);
        if (postEntities.isEmpty()) {
            redissonService.setValue("POSTS_LIST_" + authorId, postEntities, 1, TimeUnit.MINUTES);
            return Collections.emptyList();
        }
        redissonService.setValue("POSTS_LIST_" + authorId, postEntities, 10, TimeUnit.MINUTES);
        return postEntities;
    }

    @Override
    public PostEntity getPosts(Long postId) {
        PostEntity postEntity = redissonService.getValue("POSTS_" + postId);
        if (postEntity != null) {
            return postEntity;
        }
        postEntity = postsRepository.getPosts(postId);
        if (postEntity == null) {
            redissonService.setValue("POSTS_" + postId, postEntity, 1, TimeUnit.MINUTES);
            return postEntity;
        }
        redissonService.setValue("POSTS_" + postId, postEntity, 10, TimeUnit.MINUTES);
        return postEntity;
    }

    @Override
    public void deletePosts(Long postId, Long authorId) {
        redissonService.remove("POSTS_" + postId);
        int result = postsRepository.deletePosts(postId, authorId);
        if (result == 0) {
            throw new AppException("删除失败");
        }
    }

    @Override
    public void likePosts(LikePostsEntity likePostsEntity) {
        // 查询点赞列表缓存
        RSet<Object> postsLikesSet = redissonClientService.getSet("POSTS_LIKES_" + likePostsEntity.getPostsId());
        if (postsLikesSet.contains(likePostsEntity.getUserId())) {
            log.info("用户已经点赞过");
            return;
        }
        // 添加点赞用户
        postsLikesSet.add(likePostsEntity.getUserId());

        // 操作数据库 - 放入延迟队列
        postsCountService.postsLikeCountConsumeSendQueue(new PostsLikeCountVO(likePostsEntity));
    }

    @Override
    public void unLikePosts(LikePostsEntity likePostsEntity) {
        RSet<Object> postsLikesSet = redissonClientService.getSet("POSTS_LIKES_" + likePostsEntity.getPostsId());
        if (!postsLikesSet.contains(likePostsEntity.getUserId())) {
            log.info("用户未点赞过");
            return;
        }
        postsLikesSet.remove(likePostsEntity.getUserId());
        postsCountService.postsLikeCountConsumeSendQueue(new PostsLikeCountVO(likePostsEntity));
    }

    @Override
    public void collectPosts(CollectPostsEntity collectPostsEntity) {
        RSet<Object> postsCollectSet = redissonClientService.getSet("POSTS_COLLECT_" + collectPostsEntity.getPostsId());
        if (postsCollectSet.contains(collectPostsEntity.getUserId())) {
            log.info("用户已经收藏过");
            return;
        }
        postsCollectSet.add(collectPostsEntity.getUserId());
        postsRepository.updateCollectPostsCount(collectPostsEntity);
    }

    @Override
    public void unCollectPosts(CollectPostsEntity collectPostsEntity) {
        RSet<Object> postsCollectSet = redissonClientService.getSet("POSTS_COLLECT_" + collectPostsEntity.getPostsId());
        if (!postsCollectSet.contains(collectPostsEntity.getUserId())) {
            log.info("用户未收藏过");
            return;
        }
        postsCollectSet.remove(collectPostsEntity.getUserId());
        postsRepository.updateCollectPostsCount(collectPostsEntity);
    }

    @Override
    public List<PostsContentEntity> queryAll() {
        List<PostsContentEntity> postEntities = redissonService.getValue("POSTS_ALL_LIST");
        if (postEntities != null) {
            return postEntities;
        }
        postEntities = postsRepository.findAll();
        if (postEntities.isEmpty()) {
            redissonService.setValue("POSTS_ALL_LIST", postEntities, 10, TimeUnit.MINUTES);
            return Collections.emptyList();
        }
        redissonService.setValue("POSTS_ALL_LIST", postEntities, 60, TimeUnit.MINUTES);
        return postEntities;
    }

}